package com.penghaisoft.microwms.materialhand.web.intowarehouse.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.penghaisoft.microwms.common.Constant;
import com.penghaisoft.microwms.common.data.model.MdModel;
import com.penghaisoft.microwms.common.dto.RawBarcodeDto;
import com.penghaisoft.microwms.common.dto.TransResult;
import com.penghaisoft.microwms.common.service.BaseService;
import com.penghaisoft.microwms.common.wms.model.RawBack;
import com.penghaisoft.microwms.common.wms.model.RawBarcode;
import com.penghaisoft.microwms.common.wms.model.RawCarCheckIn;
import com.penghaisoft.microwms.common.wms.model.RawContractChange;
import com.penghaisoft.microwms.common.wms.model.RawStorageSn;
import com.penghaisoft.microwms.materialhand.web.backmat.dao.RawBackMapper;
import com.penghaisoft.microwms.materialhand.web.intowarehouse.service.IIntoWarehouseService;
import com.penghaisoft.microwms.materialhand.web.model.dao.MdModelMapper;
import com.penghaisoft.microwms.materialhand.web.rawbarcode.dao.RawBarcodeMapper;
import com.penghaisoft.microwms.materialhand.web.rawbarcode.dao.RawCarCheckInMapper;
import com.penghaisoft.microwms.materialhand.web.storage.dao.RawContractChangeMapper;
import com.penghaisoft.microwms.materialhand.web.storage.dao.RawStorageSnMapper;

/**
 * @Description 原材料入库
 * @author luoteng
 * @date 2018年5月28日 上午11:10:01 
 * @version 1.0
 */
@Service("intoWarehouseService")
public class IntoWarehouseServiceImpl extends BaseService implements IIntoWarehouseService {

	@Autowired
	private RawBarcodeMapper rawBarcodeMapper;
	
    @Autowired
    private RawStorageSnMapper rawStorageSnMapper;
    
    @Resource
	private RawCarCheckInMapper rawCarCheckInMapper;
    
    @Resource
	private MdModelMapper mdModelMapper;
    
    @Autowired
	private RawContractChangeMapper rawContractChangeMapper;
    
    @Autowired
    private RawBackMapper rawBackMapper;
    
    /** 
     * @Title scanBarcode
     * @Description 原材料扫码入库
     * @author luoteng
     * @date 2018年5月28日:下午4:56:55
     * @param rawBarcodeDto
     * @return TransResult
     */
    @Transactional
    @Override
    public TransResult scanBarcode(RawBarcodeDto rawBarcodeDto){
    	TransResult result = new TransResult();
        result.setCode(Constant.SUCCESS);
        
        Date now = new Date();
        
        RawBarcode rawBarcode = new RawBarcode();
        rawBarcode.setBarcode(rawBarcodeDto.getBarcode());
        rawBarcode.setActiveFlag("1");
        
        List<RawBarcode> barList = rawBarcodeMapper.queryByAny(rawBarcode);
        if(barList == null || barList.isEmpty()){
        	result.setCode(Constant.FAIL);
            result.setMsg("该条码不存在。");
            return result;
        }else if(barList.size() > 1){
        	result.setCode(Constant.FAIL);
            result.setMsg("该条码重复。");
            return result;
        }else{
        	RawBarcode tmp = barList.get(0);
        	
        	rawBarcodeMapper.updateBySelect(tmp);
        	
        	if(!tmp.getContractNo().equals(rawBarcodeDto.getContractNo())){
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码所属合同号与输入的合同号不符。");
                return result;
        	}
        	
        	RawStorageSn sn = new RawStorageSn();
            sn.setBarcode(rawBarcodeDto.getBarcode());
            sn.setActiveFlag("1");
            
            List<RawStorageSn> snList = rawStorageSnMapper.queryByAny(sn);
            List<RawStorageSn> rtnList = new ArrayList<RawStorageSn>();
            if(snList != null && !snList.isEmpty()){
            	result.setCode(Constant.FAIL);
                result.setMsg("该条码已经入库。");
                return result;
            }else{
                if (Constant.MODEL_W.equals(tmp.getModelType())
                        || Constant.MODEL_PE.equals(tmp.getModelType()) || Constant.MODEL_Z.equals(tmp.getModelType())
                        || Constant.MODEL_LDXG.equals(tmp.getModelType())  || Constant.MODEL_DXF.equals(tmp.getModelType())
                        || Constant.MODEL_DLF.equals(tmp.getModelType())  || Constant.MODEL_LHF.equals(tmp.getModelType())){
                    if (rawBarcodeDto.getAmount() == null){
                        result.setCode(Constant.FAIL);
                        result.setMsg("请输入长度！");
                        return result;
                    }
//                    String a = "^\\d+(\\.\\d+)?";
                    String b = "[0-9]{1,}(\\.[0-9]{1,})?";
                    Pattern pattern = Pattern.compile(b);
                    Matcher matcher = pattern.matcher(rawBarcodeDto.getAmount().toString());
                    Boolean isNt = matcher.matches();
                    if (isNt){
                        sn.setAmount(rawBarcodeDto.getAmount());
                        tmp.setAmount(rawBarcodeDto.getAmount());
                    }else {
                        result.setCode(Constant.FAIL);
                        result.setMsg("输入的长度不是数字格式！");
                        return result;
                    }
                }else if(Constant.MODEL_L.equals(tmp.getModelType())) {
                	if(rawBarcodeDto.getAmount() == null) {
//                    	螺纹钢管默认长度为12
                        sn.setAmount(new BigDecimal("12"));
                	}else {
                		String b = "[0-9]{1,}(\\.[0-9]{1,})?";
                        Pattern pattern = Pattern.compile(b);
                        Matcher matcher = pattern.matcher(rawBarcodeDto.getAmount().toString());
                        Boolean isNt = matcher.matches();
                        if (isNt){
                            sn.setAmount(rawBarcodeDto.getAmount());
                            tmp.setAmount(rawBarcodeDto.getAmount());
                        }else {
                            result.setCode(Constant.FAIL);
                            result.setMsg("输入的长度不是数字格式！");
                            return result;
                        }
                	}
                }else if(Constant.MODEL_LDXG.equals(tmp.getModelType())){
					if(rawBarcodeDto.getAmount() == null) {
//                    	螺纹钢管默认长度为12
						sn.setAmount(new BigDecimal("6"));
					}else {
						String b = "[0-9]{1,}(\\.[0-9]{1,})?";
						Pattern pattern = Pattern.compile(b);
						Matcher matcher = pattern.matcher(rawBarcodeDto.getAmount().toString());
						Boolean isNt = matcher.matches();
						if (isNt){
							sn.setAmount(rawBarcodeDto.getAmount());
							tmp.setAmount(rawBarcodeDto.getAmount());
						}else {
							result.setCode(Constant.FAIL);
							result.setMsg("输入的长度不是数字格式！");
							return result;
						}
					}
				}else {
//                	管件长度默认为1
                    sn.setAmount(new BigDecimal("1"));
                    tmp.setAmount(new BigDecimal("1"));
                }
                
            	tmp.setLastModifiedBy(rawBarcodeDto.getLoginName());
            	tmp.setGmtModified(now);
//            	是否合格：0-不合格 1-合格
            	tmp.setUserDefined6(rawBarcodeDto.getIsQualified());
//            	不合格原因
            	tmp.setUserDefined7(rawBarcodeDto.getNotQualifiedReason());
            	
            	rtnList.add(sn);
            	result.setList(rtnList);
            	
//            	是否合格：0-不合格 1-合格
            	if(rawBarcodeDto.getIsQualified() != null && rawBarcodeDto.getIsQualified().equals("0")){
//                	入库状态：0 未入库 1已入库
                	tmp.setUserDefined1("0");
                	rawBarcodeMapper.updateBySelect(tmp);
                	
                	return result;
            	}else{
//                	入库状态：0 未入库 1已入库
                	tmp.setUserDefined1("1");
            	}
            	rawBarcodeMapper.updateBySelect(tmp);
            	
            	sn.setUnit(tmp.getUnit());
            	sn.setContractNo(rawBarcodeDto.getContractNo());
            	sn.setModel(tmp.getModel());
//            	sn.setModelDesc(tmp.getModelDesc() == null ? "" : tmp.getModelDesc());
            	sn.setModelDesc(tmp.getModelDesc());
            	sn.setModelType(tmp.getModelType());
            	sn.setType(tmp.getType());
//            	先写默认值，后续再改
            	sn.setWlCode(rawBarcodeDto.getWlCode());
//            	0可用；1 冻结；2 已出库
            	sn.setBarcodeStatus("0");
            	sn.setCreateBy(rawBarcodeDto.getLoginName());
            	sn.setGmtCreate(now);
//            	供应商代码
            	sn.setUserDefined2(tmp.getUserDefined5());
            	
//            	类型：0正品，1样品
            	sn.setType("0");
            	
            	MdModel t = new MdModel();
            	t.setModel(tmp.getModel());
            	t.setActiveFlag("1");
            	List<MdModel> modelList = mdModelMapper.queryByAny(t);
            	if(modelList != null && !modelList.isEmpty()){
            		MdModel tmpModel = modelList.get(0);
//            		货主（0：本公司 1：外公司）
            		sn.setUserDefined3(tmpModel.getUserDefined3());
            	}
            	
            	rawStorageSnMapper.create(sn);
            	
            	RawCarCheckIn rawCarCheckIn = new RawCarCheckIn();
            	rawCarCheckIn.setCheckInNo(tmp.getUserDefined2());
            	rawCarCheckIn.setModel(tmp.getModel());
            	rawCarCheckIn.setActiveFlag("1");
            	
            	List<RawCarCheckIn> ckInList = rawCarCheckInMapper.queryByAny(rawCarCheckIn);
            	if(ckInList != null && !ckInList.isEmpty()){
            		RawCarCheckIn upOb = new RawCarCheckIn();
            		upOb.setCheckInId(ckInList.get(0).getCheckInId());
            		upOb.setInAmountAdd(1);
            		upOb.setLastModifiedBy(rawBarcodeDto.getLoginName());
            		upOb.setGmtModified(now);
            		
            		rawCarCheckInMapper.updateBySelect(upOb);
            	}
            }
        }
        
        return result;
    }
    
    /** 
     * @Title delBarcode
     * @Description 退扫条码
     * @author luoteng
     * @date 2018年5月29日:下午1:30:46
     * @param rawBarcodeDto
     * @return TransResult
     */
    @Transactional
    @Override
    public TransResult delBarcode(RawBarcodeDto rawBarcodeDto){
    	TransResult result = new TransResult();
        result.setCode(Constant.SUCCESS);
        
        Date now = new Date();
        
        RawBarcode rawBarcode1 = new RawBarcode();
        rawBarcode1.setBarcode(rawBarcodeDto.getBarcode());
        rawBarcode1.setActiveFlag("1");
        
        List<RawBarcode> barList1 = rawBarcodeMapper.queryByAny(rawBarcode1);
        if(barList1 != null && !barList1.isEmpty()){
        	RawBarcode tmp = barList1.get(0);
        	
        	if(!tmp.getContractNo().equals(rawBarcodeDto.getContractNo())){
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码所属合同号与输入的合同号不符。");
                return result;
        	}
        	
//        	入库状态：0 未入库 1已入库
        	if(tmp.getUserDefined1() != null && tmp.getUserDefined1().equals("0")){
//        		是否合格：0-不合格 1-合格
        		if(tmp.getUserDefined6() != null && tmp.getUserDefined6().equals("0")){
//                	入库状态：0 未入库 1已入库
                	tmp.setUserDefined1("0");
                	tmp.setLastModifiedBy(rawBarcodeDto.getLoginName());
                	tmp.setGmtModified(now);
//                	是否合格：0-不合格 1-合格
                	tmp.setUserDefined6("1");
//                	不合格原因
                	tmp.setUserDefined7(" ");
                	rawBarcodeMapper.updateBySelect(tmp);
                	
                	return result;
        		}
        	}
        }
        
        RawStorageSn sn = new RawStorageSn();
        sn.setBarcode(rawBarcodeDto.getBarcode());
        sn.setActiveFlag("1");
        
        List<RawStorageSn> snList = rawStorageSnMapper.queryByAny(sn);
        if(snList == null || snList.isEmpty()){
        	result.setCode(Constant.FAIL);
            result.setMsg("该条码不存在！");
            return result;
        }else{
        	RawStorageSn upob = snList.get(0);
//        	0可用；1 冻结；2已出库 3 报废
        	if("1".equals(upob.getBarcodeStatus())){
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码已冻结，不能退扫!");
                return result;
        	}else if("2".equals(upob.getBarcodeStatus())){
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码已出库 ，不能退扫!");
                return result;
        	}else if("3".equals(upob.getBarcodeStatus())){
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码已报废，不能退扫!");
                return result;
        	}
        	RawBack back = new RawBack();
        	back.setBarcode(rawBarcodeDto.getBarcode());
        	back.setActiveFlag("1");
        	
        	List<RawBack> bkList = rawBackMapper.queryByAny(back);
        	if(bkList != null && !bkList.isEmpty()) {
        		for(RawBack bk : bkList) {
        			BigDecimal oldAmount = bk.getOldAmount() == null ? BigDecimal.ZERO : bk.getOldAmount();
        			BigDecimal amount = bk.getAmount() == null ? BigDecimal.ZERO : bk.getAmount();
        			if(oldAmount.compareTo(amount) != 0) {
        				result.setCode(Constant.FAIL);
                        result.setMsg("该条码发生过生产退料，且长度已改变，不能退扫!");
                        return result;
        			}
        		}
        	}
        	
        	RawContractChange rawContractChange = new RawContractChange();
        	rawContractChange.setBarcode(rawBarcodeDto.getBarcode());
        	rawContractChange.setActiveFlag("1");
        	
        	List<RawContractChange> contractChangeList = rawContractChangeMapper.queryByAny(rawContractChange);
        	if(contractChangeList != null && !contractChangeList.isEmpty()) {
        		result.setCode(Constant.FAIL);
                result.setMsg("该条码发生过合同借用，不能退扫!");
                return result;
        	}
        	
        	//'审核状态 0 审核中 1 审核通过 2审核不通过',
        	if(upob.getUserDefined4() != null){
        		if("0".equals(upob.getUserDefined4())){
        			result.setCode(Constant.FAIL);
                    result.setMsg("该条码的退扫申请正在审核中，请勿重复操作，审核通过后无需再次进行退扫操作");
                    return result;
        		}
        	}
        	
        	//查询创建时间
        	Date createTime = snList.get(0).getGmtCreate();
        	//与当前相差时间（毫秒）
            long cha = now.getTime() - createTime.getTime(); 
            //创建时间晚于当前（数据错误）
            if(cha<0){
            	result.setCode(Constant.FAIL);
                result.setMsg("时间错误");
                return result;

            }
            //相差时间（小时）
            double timeOut = cha * 1.0 / (1000 * 60 * 60);
            //超过24小时
            if(timeOut>Constant.OUTHOUR){
            	result.setCode(Constant.FAIL);
                result.setMsg("该条码已超过退扫时间"+Constant.OUTHOUR+"小时，请联系管理人员进行审核，审核通过后无需进行再次操作");
                
                upob.setUserDefined4("0");
            	upob.setUserDefined5(rawBarcodeDto.getLoginName());//记录退扫请求发起人
            	upob.setGmtModified(now);
            	//进行退扫审核操作之前，先把条码冻结。
            	upob.setBarcodeStatus("1");
            	
            	rawStorageSnMapper.updateBySelect(upob);
                
                return result;
            }
            
        	RawBarcode rawBarcode = new RawBarcode();
            rawBarcode.setBarcode(rawBarcodeDto.getBarcode());
            rawBarcode.setActiveFlag("1");
            
            List<RawBarcode> barList = rawBarcodeMapper.queryByAny(rawBarcode);
            if(barList != null && !barList.isEmpty()){
            	RawBarcode tmp = barList.get(0);
//            	入库状态：0 未入库 1已入库
            	tmp.setUserDefined1("0");
            	tmp.setLastModifiedBy(rawBarcodeDto.getLoginName());
            	tmp.setGmtModified(now);
//            	是否合格：0-不合格 1-合格
            	tmp.setUserDefined6("1");
//            	不合格原因
            	tmp.setUserDefined7(" ");
            	rawBarcodeMapper.updateBySelect(tmp);
            	
            	RawCarCheckIn rawCarCheckIn = new RawCarCheckIn();
            	rawCarCheckIn.setCheckInNo(tmp.getUserDefined2());
            	rawCarCheckIn.setModel(tmp.getModel());
            	rawCarCheckIn.setActiveFlag("1");
            	
            	List<RawCarCheckIn> ckInList = rawCarCheckInMapper.queryByAny(rawCarCheckIn);
            	if(ckInList != null && !ckInList.isEmpty()){
            		RawCarCheckIn upOb = new RawCarCheckIn();
            		upOb.setCheckInId(ckInList.get(0).getCheckInId());
            		upOb.setInAmountDel(1);
            		upOb.setLastModifiedBy(rawBarcodeDto.getLoginName());
            		upOb.setGmtModified(now);
            		
            		rawCarCheckInMapper.updateBySelect(upOb);
            	}
            	
            }
            
        	upob.setActiveFlag("0");
        	upob.setLastModifiedBy(rawBarcodeDto.getLoginName());
        	upob.setGmtModified(now);
        	
        	rawStorageSnMapper.updateBySelect(upob);
        }
        
        return result;
    }
}
